package service

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"google.golang.org/grpc/health"
	"time"
	"zxs-micro-2/zxs-micro-balance-server/logic"

	//healthpb "google.golang.org/grpc/health/grpc_health_v1"
	"net"
	"os"
	"os/signal"
	"syscall"
	"zxs-micro-2/zxs-micro-balance-server/data_store"
	"zxs-micro-2/zxs-micro-balance-server/report"
	healthUtil "zxs-micro-2/zxs-micro-healthutil/service"
	"zxs-micro-2/zxs-micro-proto/balancepb/balance"
	serverfindClient "zxs-micro-2/zxs-micro-serverfind-client/client"
	serverfindConfig "zxs-micro-2/zxs-micro-serverfind-client/config"
)

type BalanceService struct {
	balance.UnimplementedBalanceServiceServer
	serviceId    string
	dataStore    data_store.DataStoreInterface
	healthServer *health.Server
}

func (b *BalanceService) AddBalance(ctx context.Context,
	request *balance.AddBalanceRequest) (*balance.AddBalanceResponse, error) {

	return logic.AddBalanceLogic(ctx, &data_store.BalanceData{
		ServerId:      request.Server.ServerId,
		ServerType:    request.Server.ServerType,
		ServerLoad:    request.Server.Load,
		HeartBeatTime: time.Now().Unix(),
	}, b.dataStore)
}

func (b *BalanceService) CalBalance(ctx context.Context,
	request *balance.CalBalanceRequest) (*balance.CalBalanceResponse, error) {

	return logic.CalBalanceLogic(ctx, request.ServerIds, b.dataStore)
}

func (b *BalanceService) BalanceHeartBeat(ctx context.Context,
	request *balance.BalanceHeartBeatRequest) (*balance.BalanceHeartBeatResponse, error) {

	return logic.BalanceHeartBeatLogic(ctx, &data_store.BalanceData{
		ServerId:      request.Server.ServerId,
		ServerType:    request.Server.ServerType,
		ServerLoad:    request.Server.Load,
		HeartBeatTime: time.Now().Unix(),
	}, b.dataStore)
}

func InitBalanceService() {
	lis, _ := net.Listen("tcp", report.Addr)
	s := grpc.NewServer()
	healthUtil.InitHealthService(s)
	service := new(BalanceService)
	//暂时就只用local吧，后面再加配置之类的玩意进来（配置可能会做通用的配置管理服务，现在用viper做配置可能后续不太好改
	service.dataStore = data_store.GetDataStoreStruct("local")
	balance.RegisterBalanceServiceServer(s, service)
	var servErr = make(chan error)
	go func() {
		if err := s.Serve(lis); err != nil {
			servErr <- err
		}
	}()
	go service.callServerFindAddSelf(servErr)
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
	select {
	case <-sigs:
		fmt.Println("服务关闭.....")
	case shuterr := <-servErr:
		fmt.Println(shuterr)
		fmt.Println("由于出现错误，服务发现关闭......")
	}
	os.Exit(0)
}

func (s *BalanceService) callServerFindAddSelf(servErr chan error) {
	serverfindConfig.Cfg.ServerType = "balance"
	serverfindConfig.Cfg.ClientPort = ":8001"
	serverfindConfig.Cfg.ClientProtocol = "grpc"
	id, err := serverfindClient.InitServerFindClient()
	if err != nil {
		servErr <- err
	}
	s.serviceId = id
}
